package com.iflytek.jzcpx.procuracy.ocr.common.helper;

import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;

import com.google.common.primitives.Longs;
import com.iflytek.jzcpx.procuracy.ocr.common.ByteUtil;
import com.iflytek.jzcpx.procuracy.ocr.common.enums.StateEnums;
import lombok.Data;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 电子卷宗扫描文件数据传输对象
 * <p>
 * 0字节 成功失败标识  bool
 * 1-8字节  数据区长度long
 * 9-99字节 code 内容 string
 * 100-299字节  params(包含请求参数) string
 * 300-499字节  message string
 * 500-结束  数据区长度 byte[]
 */
@Data
public class DzjzDataDTO {
    protected final Logger logger = LoggerFactory.getLogger(DzjzDataDTO.class);

    /**
     * 1 表示成功
     */
    private boolean success;

    /**
     * 返回数据部分的长度
     */
    private long dataLength;

    /**
     * 成功状态码
     */
    private String code;

    /**
     * json参数
     */
    private String params;

    /**
     * 提示消息
     */
    private String message;

    @Override
    public String toString() {
        int length = data == null ? 0 : data.length;
        return "DzjzDataDTO{" + "success=" + success + ", dataLength=" + dataLength + ", code='" + code + '\'' +
               ", params='" + params + '\'' + ", message='" + message + '\'' + ", dataSize=" + length + '}';
    }

    /**
     * byte[]文件数据流
     */
    private byte[] data;

    public DzjzDataDTO() {
    }

    public DzjzDataDTO(byte[] respBytes) {
        try {
            this.decode(respBytes);
        }
        catch (Exception e) {
            logger.warn("解析赛威讯图片数据异常, {}", this, e);
            this.success = false;
        }
    }

    /**
     * @return
     */
    public byte[] getDatas() {
        try {
            if (params == null) {
                params = "";
            }
            if (message == null) {
                message = "";
            }
            return ByteUtil.getBytes(StateEnums.SUCCESS, data.length, params, message, data);
        }
        catch (Exception ex) {
            return null;
        }
    }

    public byte[] encode() {
        byte[] resultData = new byte[500 + data.length];
        resultData[0] = (byte) (success ? 1 : 0);
        ByteBuffer buffer = ByteBuffer.allocate(8);
        buffer.putLong(0, dataLength);
        byte[] dataLengthArray = buffer.array();
        System.arraycopy(dataLengthArray, 0, resultData, 1, 8);
        if (code == null) {
            code = "";
        }
        byte[] codeBytes = code.getBytes(StandardCharsets.UTF_8);
        System.arraycopy(codeBytes, 0, resultData, 9, codeBytes.length);
        byte[] paramsBytes = params.getBytes(StandardCharsets.UTF_8);
        System.arraycopy(paramsBytes, 0, resultData, 100, paramsBytes.length);

        if (message == null) {
            message = "";
        }
        byte[] msgBytes = message.getBytes(StandardCharsets.UTF_8);
        System.arraycopy(msgBytes, 0, resultData, 300, msgBytes.length);
        System.arraycopy(data, 0, resultData, 500, data.length);
        return resultData;
    }

    private void decode(byte[] respBytes) {
        if (ArrayUtils.isEmpty(respBytes)) {
            return;
        }

        success = respBytes[0] == 1;

        byte[] dataLengthBytes = ArrayUtils.subarray(respBytes, 1, 9);
        if (ArrayUtils.isNotEmpty(dataLengthBytes)) {
            dataLength = Longs.fromByteArray(ArrayUtils.subarray(respBytes, 1, 9));
        }

        byte[] codeBytes = ArrayUtils.subarray(respBytes, 9, 100);
        if (ArrayUtils.isNotEmpty(codeBytes)) {
            code = StringUtils.trim(new String(codeBytes, StandardCharsets.UTF_8));
        }

        byte[] paramsBytes = ArrayUtils.subarray(respBytes, 100, 300);
        if (ArrayUtils.isNotEmpty(paramsBytes)) {
            params = StringUtils.trim(new String(paramsBytes, StandardCharsets.UTF_8));
        }

        byte[] messageBytes = ArrayUtils.subarray(respBytes, 300, 500);
        if (ArrayUtils.isNotEmpty(messageBytes)) {
            message = StringUtils.trim(new String(messageBytes, StandardCharsets.UTF_8));
        }

        if (success) {
            data = new byte[(int) dataLength];
            System.arraycopy(respBytes, 500, data, 0, (int) dataLength);
        }
    }

}
